001 /*
002 * Created by IntelliJ IDEA.
003 * User: Wei Wang
004 * Date: 2002-9-6
005 * Time: 15:00:07
006 * To change template for new class use
007 * Code Style | Class Templates options (Tools | IDE Options).
008 */
009 package EVolve.util.overlappers;
010
011 import EVolve.visualization.*;
012 import EVolve.visualization.Dimension;
013 import EVolve.*;
014 import EVolve.exceptions.NoDataPlotException;
015 import EVolve.util.Magnifier;
016 import EVolve.data.*;
017 import javax.swing.*;
018 import javax.imageio.ImageWriter;
019 import javax.imageio.ImageIO;
020 import java.util.*;
021 import java.awt.*;
022 import java.awt.image.BufferedImage;
023 import java.awt.event.*;
024 import java.io.File;
025 import java.io.IOException;
026
027 public abstract class OverlapVisualization {
028 protected JDialog dialog;
029 protected JScrollPane panel;
030 protected AxesPanel canvas;
031 protected ArrayList visualizationList;
032 private String xAxisName,yAxisName;
033 protected EVolve.Window window;
034 protected long xMax;
035 protected ArrayList colorList;
036 protected HashSet[] fullEntitySet;
037 protected boolean noEntityAvailable;
038
039 private JPopupMenu popup;
040 private JMenu menuSort;
041 private JMenuItem[][] itemSort;
042 private JMenu[] menuDimension;
043 private JMenuItem itemSave, itemScale;
044 private ArrayList refLocation;
045 private Magnifier magnifier;
046 private AutoImage overlappedImage;
047 private boolean shift_pressed;
048
049
050 public abstract void createDialog();
051
052 public abstract boolean isOverlapable(Visualization visualToBeOverlapped);
053
054 public abstract void overlappedVisualize();
055
056 public OverlapVisualization() {
057 visualizationList = new ArrayList();
058
059 fullEntitySet = new HashSet[2];
060 fullEntitySet[0] = null;
061 fullEntitySet[1] = null;
062 noEntityAvailable = false;
063 shift_pressed = false;
064
065 panel = createPanel();
066 addPopupTrigger(canvas);
067 }
068
069 public void showWindow() {
070 createDialog();
071 Scene.getUIManager().showDialog(dialog, dialog.getWidth(), dialog.getHeight());
072 }
073
074 public void newOverlappedVisualization(OverlapVisualization oVisual) {
075 Visualization visual = (Visualization)visualizationList.get(0);
076 xAxisName = visual.getDimension()[0].getName();
077 yAxisName = visual.getDimension()[1].getName();
078 window = Scene.getUIManager().addOverlappedVisualization(oVisual);
079 createMenu();
080 }
081
082 public JPanel getPanel() {
083 return canvas;
084 }
085
086 private JScrollPane createPanel() {
087 canvas = new AxesPanel(AxesPanel.Axis_Enabled | AxesPanel.Flip_Image | AxesPanel.Scale_Image);
088 JScrollPane returnVal = new JScrollPane(canvas);
089
090 magnifier = new Magnifier(true);
091 canvas.addMouseMotionListener(new MouseMotionAdapter() {
092 public void mouseMoved(MouseEvent e) {
093 if (e.isShiftDown()) shift_pressed = true;
094 else shift_pressed = false;
095
096 if (e.isControlDown()) {
097 int x = canvas.getImageX(e.getX());
098 int y = canvas.getImageY(e.getY());
099 magnifier.convertMousePosition(canvas);
100 magnifier.showWindow(canvas.getSubImage(x,y));
101 canvas.drawZoomingArea(e.getX(),e.getY());
102 }
103 mMoved(e.getX(), e.getY());
104 }
105 });
106
107 canvas.addMouseMotionListener(new MouseMotionAdapter() {
108 public void mouseDragged(MouseEvent e) {
109 mMoved(e.getX(), e.getY());
110 }
111 });
112
113 return returnVal;
114 }
115
116 private void mMoved(int x, int y) {
117 int xIndex = canvas.getImageX(x);
118 int yIndex = canvas.getImageY(y);
119
120 if (noEntityAvailable) {
121 Scene.setStatus("No entity information available when temporal viz overlapped.");
122 } else {
123 try {
124 if (shift_pressed && (getOverlappedSortedColor(xIndex,yIndex)==null)) {
125 Scene.setStatus(" ");
126 return;
127 }
128
129 if (fullEntitySet[0].size() == 0) {
130 String hint = getEntityName(1,yIndex);
131 if (hint != null) {
132 Scene.setStatus(hint);
133 }
134 } else {
135 String xHint = getEntityName(0,xIndex), yHint = getEntityName(1, yIndex);
136
137 if ((xHint != null) && (yHint != null)) {
138 Scene.setStatus("X: " + xHint + " Y: " + yHint);
139 }
140 }
141 } catch (Exception e) {
142 System.out.println("Exception");
143 }
144 }
145 }
146
147 private void createMenu() {
148 popup = new JPopupMenu();
149
150 menuSort = new JMenu("Sort");
151 menuSort.setMnemonic(KeyEvent.VK_S);
152 menuSort.setEnabled(false);
153 popup.add(menuSort);
154
155 ArrayList tempList = new ArrayList();
156 Visualization visual = (Visualization)visualizationList.get(visualizationList.size()-1);
157 EVolve.visualization.Dimension [] dimension = visual.getDimension();
158 refLocation = new ArrayList();
159 for (int i = 0; i < dimension.length; i++) {
160 if (dimension[i] instanceof ReferenceDimension) {
161 tempList.add(new Integer(i));
162 refLocation.add(new Integer(i));
163 }
164 }
165
166 ReferenceDimension[] referenceDimension = new ReferenceDimension[tempList.size()];
167 menuDimension = new JMenu[tempList.size()];
168 itemSort = new JMenuItem[tempList.size()][];
169 for (int i = 0; i < tempList.size(); i++) {
170 int j = ((Integer)(tempList.get(i))).intValue();
171 referenceDimension[i] = (ReferenceDimension)(dimension[j]);
172 menuDimension[i] = new JMenu(visual.getDefinition().getDimensionDefinition()[j].getName());
173 menuSort.add(menuDimension[i]);
174 }
175
176 for (int i = 0; i < referenceDimension.length; i++) {
177 ArrayList comparatorList = referenceDimension[i].getComparator();
178 itemSort[i] = new JMenuItem[comparatorList.size()];
179 menuDimension[i].removeAll();
180 for (int j = 0; j < itemSort[i].length; j++) {
181 itemSort[i][j] = new JMenuItem(((EntityComparator)(comparatorList.get(j))).getName());
182 itemSort[i][j].addActionListener(new ActionListener() {
183 public void actionPerformed(ActionEvent e) {
184 selectComparator(e);
185 }
186 });
187 menuDimension[i].add(itemSort[i][j]);
188 }
189 }
190
191 itemScale = new JMenuItem("Restore");
192 itemScale.setMnemonic(KeyEvent.VK_R);
193 itemScale.addActionListener(new ActionListener() {
194 public void actionPerformed(ActionEvent e) {
195 if (e.getActionCommand().charAt(0) == 'F') {
196 canvas.scaleImage(true);
197 itemScale.setText("Restore");
198 itemScale.setActionCommand("Restore");
199 itemScale.setMnemonic(KeyEvent.VK_R);
200 } else {
201 canvas.scaleImage(false);
202 itemScale.setText("Fit Window");
203 itemScale.setActionCommand("Fit Window");
204 itemScale.setMnemonic(KeyEvent.VK_F);
205 }
206 canvas.repaint();
207 }
208 });
209 itemScale.setSelected(true);
210 popup.add(itemScale);
211
212 itemSave = new JMenuItem("Save...");
213 itemSave.setMnemonic(KeyEvent.VK_V);
214 itemSave.addActionListener(new ActionListener() {
215 public void actionPerformed(ActionEvent e) {
216 save();
217 }
218 });
219 popup.add(itemSave);
220 }
221
222 protected void showPopup(MouseEvent e) {
223 popup.show(e.getComponent(), e.getX(), e.getY());
224 }
225
226 protected void addPopupTrigger(Component component) {
227 component.addMouseListener(new MouseAdapter() {
228 public void mouseReleased(MouseEvent e) {
229 if (e.isPopupTrigger()) {
230 showPopup(e);
231 }
232 }
233
234 public void mousePressed(MouseEvent e) {
235 if (e.isPopupTrigger()) {
236 showPopup(e);
237 }
238 }
239 });
240 }
241
242 protected void enableSortMenu() {
243 menuSort.setEnabled(true);
244 Scene.getUIManager().enableFileMenus();
245 }
246
247 protected String getColorHex(Color color) {
248 String returnVal = Integer.toHexString(color.getBlue());
249 if (returnVal.length() < 2) {
250 returnVal = "0" + returnVal;
251 }
252 returnVal = Integer.toHexString(color.getGreen()) + returnVal;
253 if (returnVal.length() < 4) {
254 returnVal = "0" + returnVal;
255 }
256 returnVal = Integer.toHexString(color.getRed()) + returnVal;
257 if (returnVal.length() < 6) {
258 returnVal = "0" + returnVal;
259 }
260
261 return returnVal;
262 }
263
264 private void save() {
265 BufferedImage image = new BufferedImage(canvas.getWidth(), canvas.getHeight(), BufferedImage.TYPE_INT_RGB);
266 canvas.paint(image.getGraphics());
267 ImageWriter writer = (ImageWriter)(ImageIO.getImageWritersByFormatName("png").next());
268
269 JFileChooser fc = new JFileChooser(Scene.getUIManager().getLastResultDir());
270
271 if (fc.showSaveDialog(Scene.getFrame()) == JFileChooser.APPROVE_OPTION) {
272 File file = fc.getSelectedFile();
273 Scene.getUIManager().setLastResultDir(file.getPath());
274 try {
275 writer.setOutput(ImageIO.createImageOutputStream(file));
276 writer.write(image);
277 } catch (IOException e) {}
278 }
279
280 }
281
282 public AutoImage getSortImage() {
283 Visualization visual = null;
284 overlappedImage = new AutoImage();
285 ReferenceDimension sortedDimension[] = new ReferenceDimension[2];
286
287 xMax = Integer.MIN_VALUE;
288
289 for (int i=0; i<visualizationList.size(); i++) {
290 AutoImage image;
291 sortedDimension[0] = null;
292 sortedDimension[1] = null;
293
294 visual = (Visualization)visualizationList.get(i);
295
296 for (int j=0; j<2; j++) {
297 Dimension dim = visual.getDimension()[j];
298 if (dim instanceof ReferenceDimension)
299 sortedDimension[j] = (ReferenceDimension)dim;
300 }
301 image = visual.getImage().getSortedImage(sortedDimension[0],sortedDimension[1]);
302 int w = image.getW();
303 int h = image.getH();
304
305 for (int j=0; j<w; j++) {
306 for (int k=0; k<h; k++) {
307 if (image.getColor(j,k) == null) continue;
308
309 if (overlappedImage.getColor(j,k) == null )
310 overlappedImage.setColor(j,k,image.getColor(j,k));
311 else
312 overlappedImage.setColor(j,k,new Color(153,0,153));
313 }
314 }
315 visual.visualize();
316 if (xMax < visual.getxMax()) xMax = visual.getxMax();
317 }
318
319 String[] comparatorName = new String[2];
320 for (int i=0; i<2; i++) {
321 if (visual.getDimension()[i] instanceof ReferenceDimension) {
322 comparatorName[i] = ((ReferenceDimension)visual.getDimension()[i]).getSelectedComparatorName();
323 } else {
324 comparatorName[i] = "";
325 }
326 }
327
328 visual = (Visualization)visualizationList.get(0);
329
330 canvas.setName(timeHeader(visual.getDimension()[0]) + xAxisName + " (" + ((fullEntitySet[0].size() == 0) ? xMax : fullEntitySet[0].size())+
331 ((comparatorName[0].length()==0) ? "" : ", "+ comparatorName[0]) + ")",
332 timeHeader(visual.getDimension()[1]) + yAxisName + " (" + fullEntitySet[1].size() +
333 ((comparatorName[1].length()==0) ? "" : ", "+ comparatorName[1]) + ")");
334 return overlappedImage;
335 }
336
337 public void sort() {
338 try {
339 canvas.setImage(getSortImage().getImage());
340 canvas.repaint();
341 } catch (NoDataPlotException e) {
342 Scene.showErrorMessage(e.getMessage());
343 }
344 }
345
346 private void selectComparator(ActionEvent e) {
347 for (int i = 0; i < itemSort.length; i++) {
348 for (int j = 0; j < itemSort[i].length; j++) {
349 if (itemSort[i][j] == e.getSource()) {
350 if (itemSort[i][j].getText().equals("Temporal")) {
351 noEntityAvailable = true;
352 } else {
353 noEntityAvailable = false;
354 }
355 for (int k=0; k<visualizationList.size(); k++) {
356 Visualization visual = (Visualization)visualizationList.get(k);
357 ReferenceDimension ref = (ReferenceDimension)visual.getDimension()[((Integer)refLocation.get(i)).intValue()];
358 ref.selectComparator(j);
359 }
360 sort();
361 return;
362 }
363 }
364 }
365 }
366
367 public void unregisterOverlappedVisualization(Visualization visual) {
368 for (int i=0;i<visualizationList.size();i++) {
369 if (((Visualization)visualizationList.get(i)).getVisualizationID() == visual.getVisualizationID()) {
370 visualizationList.remove(i);
371 }
372 }
373 if (visualizationList.size() ==1) visualizationList.clear();
374 }
375
376 private String getEntityName(int dim,int index) {
377 Entity entity = null;
378 for (int i=0; i<visualizationList.size(); i++) {
379 Visualization visual = (Visualization)visualizationList.get(i);
380 if (!(visual.getDimension()[dim] instanceof ReferenceDimension)) return null;
381 ReferenceDimension ref = (ReferenceDimension)visual.getDimension()[dim];
382 entity = ref.getEntity(index);
383 if (entity != null) {
384 break;
385 }
386 }
387
388 return (entity == null) ? null : entity.getName();
389 }
390
391 private Color getOverlappedSortedColor(int x, int y) {
392 Color returnVal = null;
393 ReferenceDimension sortedDimension[] = new ReferenceDimension[2];
394 for (int i=0; i<visualizationList.size(); i++) {
395 Visualization visual = (Visualization)visualizationList.get(i);
396 for (int j=0; j<2; j++) {
397 Dimension dim = visual.getDimension()[j];
398 if (dim instanceof ReferenceDimension)
399 sortedDimension[j] = (ReferenceDimension)dim;
400 }
401 returnVal = visual.getImage().getSortedColor(sortedDimension[0],sortedDimension[1],x,y);
402 if (returnVal != null) break;
403 }
404
405 return returnVal;
406 }
407
408 private String timeHeader(Dimension dim) {
409 String property[] = dim.getDataFilter().getProperty();
410
411 if (property == null) return "";
412
413 for (int i=0; i<property.length; i++) {
414 if (property[i].equals("time"))
415 return "Time - ";
416 }
417 return "";
418 }
419
420 public void cleanup() {
421 fullEntitySet = null;
422 itemSort = null;
423 menuDimension = null;
424 magnifier.cleanup();
425 }
426 }